/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.dltk.internal.ui.refactoring.reorg;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.core.ExternalProjectFragment;
import org.eclipse.dltk.internal.core.ExternalScriptFolder;
import org.eclipse.dltk.internal.core.ExternalSourceModule;
import org.eclipse.dltk.internal.corext.refactoring.reorg.ModelElementTransfer;
import org.eclipse.dltk.internal.corext.refactoring.reorg.ParentChecker;
import org.eclipse.dltk.internal.corext.refactoring.reorg.ReorgUtils;
import org.eclipse.dltk.internal.ui.refactoring.RefactoringMessages;
import org.eclipse.dltk.internal.ui.workingsets.WorkingSetIDs;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.actions.SelectionDispatchAction;
import org.eclipse.dltk.ui.util.ExceptionHandler;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.actions.CopyFilesAndFoldersOperation;
import org.eclipse.ui.actions.CopyProjectOperation;
import org.eclipse.ui.part.ResourceTransfer;
public class PasteAction extends SelectionDispatchAction{
private final Clipboard fClipboard;
public PasteAction(IWorkbenchSite site, Clipboard clipboard) {
super(site);
Assert.isNotNull(clipboard);
fClipboard= clipboard;
setText(ReorgMessages.PasteAction_4);
setDescription(ReorgMessages.PasteAction_5);
ISharedImages workbenchImages= DLTKUIPlugin.getDefault().getWorkbench().getSharedImages();
setDisabledImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
setImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
setHoverImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
if (DLTKCore.DEBUG) {
System.err.println("Add help support here..."); //$NON-NLS-1$
}
//PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IScriptHelpContextIds.PASTE_ACTION);
}
public void selectionChanged(IStructuredSelection selection) {
// Moved condition checking to run (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=78450)
}
private Paster[] createEnabledPasters(TransferData[] availableDataTypes) throws ModelException {
Paster paster;
Shell shell = getShell();
List result= new ArrayList(2);
paster= new ProjectPaster(shell, fClipboard);
if (paster.canEnable(availableDataTypes))
result.add(paster);
paster= new ModelElementAndResourcePaster(shell, fClipboard);
if (paster.canEnable(availableDataTypes))
result.add(paster);
// paster= new TypedSourcePaster(shell, fClipboard);
// if (paster.canEnable(availableDataTypes))
// result.add(paster);
paster= new FilePaster(shell, fClipboard);
if (paster.canEnable(availableDataTypes))
result.add(paster);
paster= new WorkingSetPaster(shell, fClipboard);
if (paster.canEnable(availableDataTypes))
result.add(paster);
// paster= new TextPaster(shell, fClipboard);
// if (paster.canEnable(availableDataTypes))
// result.add(paster);
return (Paster[]) result.toArray(new Paster[result.size()]);
}
private static Object getContents(final Clipboard clipboard, final Transfer transfer, Shell shell) {
//see bug 33028 for explanation why we need this
final Object[] result= new Object[1];
shell.getDisplay().syncExec(new Runnable() {
public void run() {
result[0]= clipboard.getContents(transfer);
}
});
return result[0];
}
private static boolean isAvailable(Transfer transfer, TransferData[] availableDataTypes) {
for (int i= 0; i < availableDataTypes.length; i++) {
if (transfer.isSupportedType(availableDataTypes[i])) return true;
}
return false;
}
public void run(IStructuredSelection selection) {
try {
TransferData[] availableTypes= fClipboard.getAvailableTypes();
List elements= selection.toList();
IResource[] resources= ReorgUtils.getResources(elements);
IModelElement[] modelElements= ReorgUtils.getModelElements(elements);
IWorkingSet[] workingSets= ReorgUtils.getWorkingSets(elements);
Paster[] pasters= createEnabledPasters(availableTypes);
for (int i= 0; i < pasters.length; i++) {
if (pasters[i].canPasteOn(modelElements, resources, workingSets)) {
pasters[i].paste(modelElements, resources, workingSets, availableTypes);
return;// one is enough
}
}
MessageDialog.openError(DLTKUIPlugin.getActiveWorkbenchShell(), RefactoringMessages.OpenRefactoringWizardAction_refactoring, RefactoringMessages.OpenRefactoringWizardAction_disabled);
} catch (ModelException e) {
ExceptionHandler.handle(e, RefactoringMessages.OpenRefactoringWizardAction_refactoring, RefactoringMessages.OpenRefactoringWizardAction_exception);
} catch (InvocationTargetException e) {
ExceptionHandler.handle(e, RefactoringMessages.OpenRefactoringWizardAction_refactoring, RefactoringMessages.OpenRefactoringWizardAction_exception);
} catch (InterruptedException e) {
// OK
}
}
private abstract static class Paster{
private final Shell fShell;
private final Clipboard fClipboard2;
protected Paster(Shell shell, Clipboard clipboard){
fShell= shell;
fClipboard2= clipboard;
}
protected final Shell getShell() {
return fShell;
}
protected final Clipboard getClipboard() {
return fClipboard2;
}
protected final IResource[] getClipboardResources(TransferData[] availableDataTypes) {
Transfer transfer= ResourceTransfer.getInstance();
if (isAvailable(transfer, availableDataTypes)) {
return (IResource[])getContents(fClipboard2, transfer, getShell());
}
return null;
}
protected final IModelElement[] getClipboardScriptElements(TransferData[] availableDataTypes) {
Transfer transfer= ModelElementTransfer.getInstance();
if (isAvailable(transfer, availableDataTypes)) {
return (IModelElement[])getContents(fClipboard2, transfer, getShell());
}
return null;
}
// protected final TypedSource[] getClipboardTypedSources(TransferData[] availableDataTypes) {
// Transfer transfer= TypedSourceTransfer.getInstance();
// if (isAvailable(transfer, availableDataTypes)) {
// return (TypedSource[])getContents(fClipboard2, transfer, getShell());
// }
// return null;
// }
protected final String getClipboardText(TransferData[] availableDataTypes) {
Transfer transfer= TextTransfer.getInstance();
if (isAvailable(transfer, availableDataTypes)) {
return (String) getContents(fClipboard2, transfer, getShell());
}
return null;
}
public abstract void paste(IModelElement[] selectedScriptElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws ModelException, InterruptedException, InvocationTargetException;
public abstract boolean canEnable(TransferData[] availableTypes) throws ModelException;
public abstract boolean canPasteOn(IModelElement[] selectedScriptElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets) throws ModelException;
}
// private static class TextPaster extends Paster {
//
// private static class CuParser {
// private final IScriptProject fScriptProject;
// private final String fText;
//
// private String fTypeName;
// private String fPackageName;
//
// public CuParser(IScriptProject scriptProject, String text) {
// fScriptProject= scriptProject;
// fText= text;
// }
//
// private void parseText() {
// if (fPackageName != null)
// return;
//
// fPackageName= IProjectFragment.DEFAULT_SCRIPT_FOLDER_NAME;
// if (DLTKCore.DEBUG) {
// System.err.println("Add language dependent code here.");
// }
//// ASTParser parser= ASTParser.newParser(AST.JLS3);
//// parser.setProject(fScriptProject);
//// parser.setSource(fText.toCharArray());
//// SourceModule unit= (SourceModule) parser.createAST(null);
////
//// if (unit == null)
//// return;
////
//// int typesCount= unit.types().size();
//// if (typesCount > 0) {
//// // get first most visible type:
//// int maxVisibility= Modifier.PRIVATE;
//// for (ListIterator iter= unit.types().listIterator(typesCount); iter.hasPrevious();) {
//// AbstractTypeDeclaration type= (AbstractTypeDeclaration) iter.previous();
//// int visibility= DLTKFlags.getVisibilityCode(type);
//// if (! DLTKFlags.isHigherVisibility(maxVisibility, visibility)) {
//// maxVisibility= visibility;
//// fTypeName= type.getName().getIdentifier();
//// }
//// }
//// }
//// if (fTypeName == null)
//// return;
////
//// PackageDeclaration pack= unit.getPackage();
//// if (pack != null) {
//// fPackageName= pack.getName().getFullyQualifiedName();
//// }
// }
//
// /**
// * @return the type name, or <code>null</code> iff the text could not be parsed
// */
// public String getTypeName() {
// parseText();
// return fTypeName;
// }
//
// public String getPackageName() {
// parseText();
// return fPackageName;
// }
//
// public String getText() {
// return fText;
// }
// }
//
// private IProjectFragment fDestinationPack;
// private CuParser fCuParser;
// private TransferData[] fAvailableTypes;
//
// protected TextPaster(Shell shell, Clipboard clipboard) {
// super(shell, clipboard);
// }
//
// public boolean canEnable(TransferData[] availableTypes) {
// fAvailableTypes= availableTypes;
// return PasteAction.isAvailable(TextTransfer.getInstance(), availableTypes);
// }
//
// public boolean canPasteOn(IModelElement[] modelElements, IResource[] resources, IWorkingSet[] selectedWorkingSets) throws ModelException {
// if (selectedWorkingSets.length != 0)
// return false;
// if (resources.length != 0)
// return false; //alternative: create text file?
// if (modelElements.length != 1)
// return false;
//
// IModelElement destination= modelElements[0];
// String text= getClipboardText(fAvailableTypes);
// fCuParser= new CuParser(destination.getScriptProject(), text);
//
// if (fCuParser.getTypeName() == null)
// return false;
//
// switch (destination.getElementType()) {
// case IModelElement.JAVA_PROJECT :
// IProjectFragment[] ProjectFragments= ((IScriptProject) destination).getProjectFragments();
// for (int i= 0; i < ProjectFragments.length; i++) {
// IProjectFragment ProjectFragment= ProjectFragments[i];
// if (ProjectFragment.getKind() == IProjectFragment.K_SOURCE) {
// fDestinationPack= ProjectFragment.getScriptFolder(fCuParser.getPackageName());
// if (isWritable(fDestinationPack))
// return true;
// }
// }
// return false;
//
// case IModelElement.PACKAGE_FRAGMENT_ROOT :
// IProjectFragment ProjectFragment= (IProjectFragment) destination;
// if (ProjectFragment.getKind() == IProjectFragment.K_SOURCE) {
// fDestinationPack= ProjectFragment.getScriptFolder(fCuParser.getPackageName());
// return isWritable(fDestinationPack);
// }
// return false;
//
// case IModelElement.PACKAGE_FRAGMENT :
// fDestinationPack= (IProjectFragment) destination;
// return isWritable(fDestinationPack);
//
// case IModelElement.COMPILATION_UNIT :
// fDestinationPack= (IProjectFragment) destination.getParent();
// return isWritable(fDestinationPack);
//
// default:
// return false;
// }
// }
//
// private boolean isWritable(IProjectFragment destinationPack) {
// if (destinationPack.exists() && destinationPack.isReadOnly()) {
// return false;
// } else {
// IProjectFragment ProjectFragment= ScriptModelUtil.getProjectFragment(destinationPack);
// try {
// return ProjectFragment.exists() && ! ProjectFragment.isArchive() && ! ProjectFragment.isReadOnly()
// && ProjectFragment.getKind() == IProjectFragment.K_SOURCE;
// } catch (ScriptModelException e) {
// return false;
// }
// }
// }
//
// public void paste(IModelElement[] modelElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws ModelException, InterruptedException, InvocationTargetException{
// final IEditorPart[] editorPart= new IEditorPart[1];
//
// IWorkspaceRunnable op= new IWorkspaceRunnable() {
// public void run(IProgressMonitor pm) throws CoreException {
// pm.beginTask("", 4); //$NON-NLS-1$
//
// if (! fDestinationPack.exists())
// ScriptModelUtil.getProjectFragment(fDestinationPack).createScriptFolder(fCuParser.getPackageName(), true, new SubProgressMonitor(pm, 1));
// else
// pm.worked(1);
//
// final String cuName= fCuParser.getTypeName() + ScriptModelUtil.DEFAULT_CU_SUFFIX;
// final ISourceModule cu= fDestinationPack.getSourceModule(cuName);
// boolean alreadyExists= cu.exists();
// if (alreadyExists) {
// String msg= Messages.format(ReorgMessages.PasteAction_TextPaster_exists, new Object[] {cuName});
// boolean overwrite= MessageDialog.openQuestion(getShell(), ReorgMessages.PasteAction_TextPaster_confirmOverwriting, msg);
// if (! overwrite)
// return;
//
// editorPart[0]= openCu(cu); //Open editor before overwriting to allow undo.
// }
//
// fDestinationPack.createSourceModule(cuName, fCuParser.getText(), true, new SubProgressMonitor(pm, 1));
//
// if (!alreadyExists) {
// editorPart[0]= openCu(cu);
// }
// if (!fDestinationPack.getElementName().equals(fCuParser.getPackageName())) {
// if (fDestinationPack.getElementName().length() == 0) {
// removePackageDeclaration(cu);
// } else {
// cu.createPackageDeclaration(fDestinationPack.getElementName(), new SubProgressMonitor(pm, 1));
// }
// if (!alreadyExists && editorPart[0] != null)
// editorPart[0].doSave(new SubProgressMonitor(pm, 1)); //avoid showing error marker due to missing/wrong package declaration
// else
// pm.worked(1);
// } else {
// pm.worked(1);
// }
// BasicNewResourceWizard.selectAndReveal(cu.getResource(), PlatformUI.getWorkbench().getActiveWorkbenchWindow());
// }
//
// private void removePackageDeclaration(final ISourceModule cu) throws ModelException, CoreException {
// IPackageDeclaration[] packageDeclarations= cu.getPackageDeclarations();
// if (packageDeclarations.length != 0) {
// ITextFileBuffer buffer= null;
// try {
// buffer= RefactoringFileBuffers.acquire(cu);
// ISourceRange sourceRange= packageDeclarations[0].getSourceRange();
// buffer.getDocument().replace(sourceRange.getOffset(), sourceRange.getLength(), ""); //$NON-NLS-1$
// } catch (BadLocationException e) {
// ScriptPlugin.log(e);
// } finally {
// if (buffer != null)
// RefactoringFileBuffers.release(cu);
// }
// }
// }
// };
//
// IRunnableContext context= ScriptPlugin.getActiveWorkbenchWindow();
// if (context == null) {
// context= new BusyIndicatorRunnableContext();
// }
// PlatformUI.getWorkbench().getProgressService().runInUI(context, new WorkbenchRunnableAdapter(op), null);
//
// if (editorPart[0] != null)
// editorPart[0].getEditorSite().getPage().activate(editorPart[0]); //activate editor again, since runInUI restores previous active part
// }
//
// private IEditorPart openCu(ISourceModule cu) {
// try {
// return EditorUtility.openInEditor(cu);
// } catch (PartInitException e) {
// ScriptPlugin.log(e);
// return null;
// } catch (ScriptModelException e) {
// ScriptPlugin.log(e);
// return null;
// }
// }
// }
private static class WorkingSetPaster extends Paster {
protected WorkingSetPaster(Shell shell, Clipboard clipboard) {
super(shell, clipboard);
}
public void paste(IModelElement[] selectedScriptElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws ModelException, InterruptedException, InvocationTargetException {
IWorkingSet workingSet= selectedWorkingSets[0];
Set elements= new HashSet(Arrays.asList(workingSet.getElements()));
IModelElement[] modelElements= getClipboardScriptElements(availableTypes);
if (modelElements != null) {
for (int i= 0; i < modelElements.length; i++) {
if (!ReorgUtils.containsElementOrParent(elements, modelElements[i]))
elements.add(modelElements[i]);
}
}
IResource[] resources= getClipboardResources(availableTypes);
if (resources != null) {
List realScriptElements= new ArrayList();
List realResource= new ArrayList();
ReorgUtils.splitIntoModelElementsAndResources(resources, realScriptElements, realResource);
for (Iterator iter= realScriptElements.iterator(); iter.hasNext();) {
IModelElement element= (IModelElement)iter.next();
if (!ReorgUtils.containsElementOrParent(elements, element))
elements.add(element);
}
for (Iterator iter= realResource.iterator(); iter.hasNext();) {
IResource element= (IResource)iter.next();
if (!ReorgUtils.containsElementOrParent(elements, element))
elements.add(element);
}
}
workingSet.setElements((IAdaptable[])elements.toArray(new IAdaptable[elements.size()]));
}
public boolean canEnable(TransferData[] availableTypes) throws ModelException {
return isAvailable(ResourceTransfer.getInstance(), availableTypes) ||
isAvailable(ModelElementTransfer.getInstance(), availableTypes);
}
public boolean canPasteOn(IModelElement[] selectedScriptElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets) throws ModelException {
if (selectedResources.length != 0 || selectedScriptElements.length != 0 || selectedWorkingSets.length != 1)
return false;
IWorkingSet ws= selectedWorkingSets[0];
return !WorkingSetIDs.OTHERS.equals(ws.getId());
}
}
private static class ProjectPaster extends Paster{
protected ProjectPaster(Shell shell, Clipboard clipboard) {
super(shell, clipboard);
}
public boolean canEnable(TransferData[] availableDataTypes) {
boolean resourceTransfer= isAvailable(ResourceTransfer.getInstance(), availableDataTypes);
boolean modelElementTransfer= isAvailable(ModelElementTransfer.getInstance(), availableDataTypes);
if (! modelElementTransfer)
return canPasteSimpleProjects(availableDataTypes);
if (! resourceTransfer)
return canPasteScriptProjects(availableDataTypes);
return canPasteScriptProjects(availableDataTypes) && canPasteSimpleProjects(availableDataTypes);
}
public void paste(IModelElement[] modelElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) {
pasteProjects(availableTypes);
}
private void pasteProjects(TransferData[] availableTypes) {
pasteProjects(getProjectsToPaste(availableTypes));
}
private void pasteProjects(IProject[] projects){
Shell shell= getShell();
for (int i = 0; i < projects.length; i++) {
new CopyProjectOperation(shell).copyProject(projects[i]);
}
}
private IProject[] getProjectsToPaste(TransferData[] availableTypes) {
IResource[] resources= getClipboardResources(availableTypes);
IModelElement[] modelElements= getClipboardScriptElements(availableTypes);
Set result= new HashSet();
if (resources != null)
result.addAll(Arrays.asList(resources));
if (modelElements != null)
result.addAll(Arrays.asList(ReorgUtils.getNotNulls(ReorgUtils.getResources(modelElements))));
Assert.isTrue(result.size() > 0);
return (IProject[]) result.toArray(new IProject[result.size()]);
}
public boolean canPasteOn(IModelElement[] modelElements, IResource[] resources, IWorkingSet[] selectedWorkingSets) {
return selectedWorkingSets.length == 0; // Can't paste on working sets here
}
private boolean canPasteScriptProjects(TransferData[] availableDataTypes) {
IModelElement[] modelElements= getClipboardScriptElements(availableDataTypes);
return modelElements != null &&
modelElements.length != 0 &&
! ReorgUtils.hasElementsNotOfType(modelElements, IModelElement.SCRIPT_PROJECT);
}
private boolean canPasteSimpleProjects(TransferData[] availableDataTypes) {
IResource[] resources= getClipboardResources(availableDataTypes);
if (resources == null || resources.length == 0) return false;
for (int i= 0; i < resources.length; i++) {
if (resources[i].getType() != IResource.PROJECT || ! ((IProject)resources[i]).isOpen())
return false;
}
return true;
}
}
private static class FilePaster extends Paster{
protected FilePaster(Shell shell, Clipboard clipboard) {
super(shell, clipboard);
}
public void paste(IModelElement[] modelElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws ModelException {
String[] fileData= getClipboardFiles(availableTypes);
if (fileData == null)
return;
IContainer container= getAsContainer(getTarget(modelElements, resources));
if (container == null)
return;
new CopyFilesAndFoldersOperation(getShell()).copyFiles(fileData, container);
}
private Object getTarget(IModelElement[] modelElements, IResource[] resources) {
if (modelElements.length + resources.length == 1){
if (modelElements.length == 1)
return modelElements[0];
else
return resources[0];
} else
return getCommonParent(modelElements, resources);
}
public boolean canPasteOn(IModelElement[] modelElements, IResource[] resources, IWorkingSet[] selectedWorkingSets) throws ModelException {
Object target= getTarget(modelElements, resources);
return target != null && canPasteFilesOn(getAsContainer(target)) && selectedWorkingSets.length == 0;
}
public boolean canEnable(TransferData[] availableDataTypes) throws ModelException {
return isAvailable(FileTransfer.getInstance(), availableDataTypes);
}
private boolean canPasteFilesOn(Object target) {
boolean isScriptFolder= target instanceof IProjectFragment;
boolean isScriptProject= target instanceof IScriptProject;
boolean isProjectFragment= target instanceof IProjectFragment;
boolean isContainer= target instanceof IContainer;
if( target instanceof ExternalProjectFragment || target instanceof ExternalScriptFolder || target instanceof ExternalSourceModule ) {
return false;
}
if (!(isScriptFolder || isScriptProject || isProjectFragment || isContainer))
return false;
if (isContainer) {
return true;
} else {
IModelElement element= (IModelElement)target;
return !element.isReadOnly();
}
}
private IContainer getAsContainer(Object target) throws ModelException{
if (target == null)
return null;
if (target instanceof IContainer)
return (IContainer)target;
if (target instanceof IFile)
return ((IFile)target).getParent();
return getAsContainer(((IModelElement)target).getCorrespondingResource());
}
private String[] getClipboardFiles(TransferData[] availableDataTypes) {
Transfer transfer= FileTransfer.getInstance();
if (isAvailable(transfer, availableDataTypes)) {
return (String[])getContents(getClipboard(), transfer, getShell());
}
return null;
}
private Object getCommonParent(IModelElement[] modelElements, IResource[] resources) {
return new ParentChecker(resources, modelElements).getCommonParent();
}
}
private static class ModelElementAndResourcePaster extends Paster {
protected ModelElementAndResourcePaster(Shell shell, Clipboard clipboard) {
super(shell, clipboard);
}
private TransferData[] fAvailableTypes;
public void paste(IModelElement[] modelElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws ModelException, InterruptedException, InvocationTargetException{
IResource[] clipboardResources= getClipboardResources(availableTypes);
if (clipboardResources == null)
clipboardResources= new IResource[0];
IModelElement[] clipboardScriptElements= getClipboardScriptElements(availableTypes);
if (clipboardScriptElements == null)
clipboardScriptElements= new IModelElement[0];
Object destination= getTarget(modelElements, resources);
if (destination instanceof IModelElement) {
ReorgCopyStarter.create(clipboardScriptElements, clipboardResources, (IModelElement)destination).run(getShell());
}
else if (destination instanceof IResource) {
ReorgCopyStarter.create(clipboardScriptElements, clipboardResources, (IResource)destination).run(getShell());
}
}
private Object getTarget(IModelElement[] modelElements, IResource[] resources) {
if (modelElements.length + resources.length == 1){
if (modelElements.length == 1)
return modelElements[0];
else
return resources[0];
} else
return getCommonParent(modelElements, resources);
}
private Object getCommonParent(IModelElement[] modelElements, IResource[] resources) {
return new ParentChecker(resources, modelElements).getCommonParent();
}
public boolean canPasteOn(IModelElement[] modelElements, IResource[] resources, IWorkingSet[] selectedWorkingSets) throws ModelException {
if (selectedWorkingSets.length != 0)
return false;
IResource[] clipboardResources= getClipboardResources(fAvailableTypes);
if (clipboardResources == null)
clipboardResources= new IResource[0];
IModelElement[] clipboardScriptElements= getClipboardScriptElements(fAvailableTypes);
if (clipboardScriptElements == null)
clipboardScriptElements= new IModelElement[0];
Object destination= getTarget(modelElements, resources);
if (destination instanceof IModelElement) {
return ReorgCopyStarter.create(clipboardScriptElements, clipboardResources, (IModelElement)destination) != null;
}
if (destination instanceof IResource) {
return ReorgCopyStarter.create(clipboardScriptElements, clipboardResources, (IResource)destination) != null;
}
return false;
}
public boolean canEnable(TransferData[] availableTypes) {
fAvailableTypes= availableTypes;
return isAvailable(ModelElementTransfer.getInstance(), availableTypes) || isAvailable(ResourceTransfer.getInstance(), availableTypes);
}
}
// private static class TypedSourcePaster extends Paster{
//
// protected TypedSourcePaster(Shell shell, Clipboard clipboard) {
// super(shell, clipboard);
// }
// private TransferData[] fAvailableTypes;
//
// public boolean canEnable(TransferData[] availableTypes) throws ModelException {
// fAvailableTypes= availableTypes;
// return isAvailable(TypedSourceTransfer.getInstance(), availableTypes);
// }
//
// public boolean canPasteOn(IModelElement[] selectedScriptElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets) throws ModelException {
// if (selectedResources.length != 0 || selectedWorkingSets.length != 0)
// return false;
// TypedSource[] typedSources= getClipboardTypedSources(fAvailableTypes);
// Object destination= getTarget(selectedScriptElements, selectedResources);
// if (destination instanceof IScriptElement)
// return ReorgTypedSourcePasteStarter.create(typedSources, (IScriptElement)destination) != null;
// return false;
// }
//
// public void paste(IModelElement[] selectedScriptElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws ModelException, InterruptedException, InvocationTargetException {
// TypedSource[] typedSources= getClipboardTypedSources(availableTypes);
// IScriptElement destination= getTarget(selectedScriptElements, selectedResources);
// ReorgTypedSourcePasteStarter.create(typedSources, destination).run(getShell());
// }
//
// private static IModelElement getTarget(IModelElement[] selectedScriptElements, IResource[] selectedResources) {
// Assert.isTrue(selectedResources.length == 0);
// if (selectedScriptElements.length == 1)
// return getAsTypeOrCu(selectedScriptElements[0]);
// Object parent= new ParentChecker(selectedResources, selectedScriptElements).getCommonParent();
// if (parent instanceof IModelElement)
// return getAsTypeOrCu((IModelElement)parent);
// return null;
// }
// private static IModelElement getAsTypeOrCu(IModelElement element) {
// //try to get type first
// if (element.getElementType() == IModelElement.COMPILATION_UNIT || element.getElementType() == IModelElement.TYPE)
// return element;
// IModelElement ancestorType= element.getAncestor(IModelElement.TYPE);
// if (ancestorType != null)
// return ancestorType;
// return ReorgUtils.getSourceModule(element);
// }
// private static class ReorgTypedSourcePasteStarter {
//
// private final PasteTypedSourcesRefactoring fPasteRefactoring;
//
// private ReorgTypedSourcePasteStarter(PasteTypedSourcesRefactoring pasteRefactoring) {
// Assert.isNotNull(pasteRefactoring);
// fPasteRefactoring= pasteRefactoring;
// }
//
// public static ReorgTypedSourcePasteStarter create(TypedSource[] typedSources, IModelElement destination) {
// Assert.isNotNull(typedSources);
// Assert.isNotNull(destination);
// PasteTypedSourcesRefactoring pasteRefactoring= PasteTypedSourcesRefactoring.create(typedSources);
// if (pasteRefactoring == null)
// return null;
// if (! pasteRefactoring.setDestination(destination).isOK())
// return null;
// return new ReorgTypedSourcePasteStarter(pasteRefactoring);
// }
//
// public void run(Shell parent) throws InterruptedException, InvocationTargetException {
// IRunnableContext context= new ProgressMonitorDialog(parent);
// new RefactoringExecutionHelper(fPasteRefactoring, RefactoringCore.getConditionCheckingFailedSeverity(), false, parent, context).perform(false);
// }
// }
// private static class PasteTypedSourcesRefactoring extends Refactoring {
//
// private final TypedSource[] fSources;
// private IModelElement fDestination;
//
// static PasteTypedSourcesRefactoring create(TypedSource[] sources){
// if (! isAvailable(sources))
// return null;
// return new PasteTypedSourcesRefactoring(sources);
// }
// public RefactoringStatus setDestination(IModelElement destination) {
// fDestination= destination;
// if (ReorgUtils.getSourceModule(destination) == null)
// return RefactoringStatus.createFatalErrorStatus(ReorgMessages.PasteAction_wrong_destination);
// if (! destination.exists())
// return RefactoringStatus.createFatalErrorStatus(ReorgMessages.PasteAction_element_doesnot_exist);
// if (! canPasteAll(destination))
// return RefactoringStatus.createFatalErrorStatus(ReorgMessages.PasteAction_invalid_destination);
// return new RefactoringStatus();
// }
// private boolean canPasteAll(IModelElement destination) {
// for (int i= 0; i < fSources.length; i++) {
// if (! canPaste(fSources[i].getType(), destination))
// return false;
// }
// return true;
// }
// private static boolean canPaste(int elementType, IModelElement destination) {
// IType ancestorType= getAncestorType(destination);
// if (ancestorType != null)
// return canPasteToType(elementType);
// return canPasteToCu(elementType);
// }
// private static boolean canPasteToType(int elementType) {
// return elementType == IModelElement.TYPE ||
// elementType == IModelElement.FIELD ||
// elementType == IModelElement.INITIALIZER ||
// elementType == IModelElement.METHOD;
// }
// private static boolean canPasteToCu(int elementType) {
// return elementType == IModelElement.PACKAGE_DECLARATION ||
// elementType == IModelElement.TYPE ||
// elementType == IModelElement.IMPORT_DECLARATION;
// }
// PasteTypedSourcesRefactoring(TypedSource[] sources){
// Assert.isNotNull(sources);
// Assert.isTrue(sources.length != 0);
// fSources= sources;
// }
//
// private static boolean isAvailable(TypedSource[] sources) {
// return sources != null && sources.length > 0;
// }
//
// public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
// return new RefactoringStatus();
// }
//
// public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
// RefactoringStatus result= Checks.validateModifiesFiles(
// ResourceUtil.getFiles(new ISourceModule[]{getDestinationCu()}), getValidationContext());
// return result;
// }
//
// public Change createChange(IProgressMonitor pm) throws CoreException {
// ASTParser p= ASTParser.newParser(AST.JLS3);
// p.setSource(getDestinationCu());
// SourceModule cuNode= (SourceModule) p.createAST(pm);
// ASTRewrite rewrite= ASTRewrite.create(cuNode.getAST());
// TypedSource source= null;
// for (int i= fSources.length - 1; i >= 0; i--) {
// source= fSources[i];
// final ASTNode destination= getDestinationNodeForSourceElement(fDestination, source.getType(), cuNode);
// if (destination != null) {
// if (destination instanceof SourceModule)
// insertToCu(rewrite, createNewNodeToInsertToCu(source, rewrite), (SourceModule) destination);
// else if (destination instanceof AbstractTypeDeclaration)
// insertToType(rewrite, createNewNodeToInsertToType(source, rewrite), (AbstractTypeDeclaration) destination);
// }
// }
// final SourceModuleChange result= new SourceModuleChange(ReorgMessages.PasteAction_change_name, getDestinationCu());
// try {
// ITextFileBuffer buffer= RefactoringFileBuffers.acquire(getDestinationCu());
// TextEdit rootEdit= rewrite.rewriteAST(buffer.getDocument(), fDestination.getScriptProject().getOptions(true));
// if (getDestinationCu().isWorkingCopy())
// result.setSaveMode(TextFileChange.LEAVE_DIRTY);
// TextChangeCompatibility.addTextEdit(result, ReorgMessages.PasteAction_edit_name, rootEdit);
// } finally {
// RefactoringFileBuffers.release(getDestinationCu());
// }
// return result;
// }
//
// private static void insertToType(ASTRewrite rewrite, ASTNode node, AbstractTypeDeclaration typeDeclaration) {
// switch (node.getNodeType()) {
// case ASTNode.ANNOTATION_TYPE_DECLARATION:
// case ASTNode.ENUM_DECLARATION:
// case ASTNode.TYPE_DECLARATION:
// case ASTNode.METHOD_DECLARATION:
// case ASTNode.FIELD_DECLARATION:
// case ASTNode.INITIALIZER:
// rewrite.getListRewrite(typeDeclaration, typeDeclaration.getBodyDeclarationsProperty()).insertAt(node, ASTNodes.getInsertionIndex((BodyDeclaration) node, typeDeclaration.bodyDeclarations()), null);
// break;
// default:
// Assert.isTrue(false, String.valueOf(node.getNodeType()));
// }
// }
//
// private static void insertToCu(ASTRewrite rewrite, ASTNode node, SourceModule cuNode) {
// switch (node.getNodeType()) {
// case ASTNode.TYPE_DECLARATION:
// case ASTNode.ENUM_DECLARATION:
// case ASTNode.ANNOTATION_TYPE_DECLARATION:
// rewrite.getListRewrite(cuNode, SourceModule.TYPES_PROPERTY).insertAt(node, ASTNodes.getInsertionIndex((AbstractTypeDeclaration) node, cuNode.types()), null);
// break;
// case ASTNode.IMPORT_DECLARATION:
// rewrite.getListRewrite(cuNode, SourceModule.IMPORTS_PROPERTY).insertLast(node, null);
// break;
// case ASTNode.PACKAGE_DECLARATION:
// // only insert if none exists
// if (cuNode.getPackage() == null)
// rewrite.set(cuNode, SourceModule.PACKAGE_PROPERTY, node, null);
// break;
// default:
// Assert.isTrue(false, String.valueOf(node.getNodeType()));
// }
// }
//
// /**
// * @return an AbstractTypeDeclaration, a SourceModule, or null
// */
// private ASTNode getDestinationNodeForSourceElement(IModelElement destination, int kind, SourceModule unit) throws ModelException {
// final IType ancestor= getAncestorType(destination);
// if (ancestor != null)
// return ASTNodeSearchUtil.getAbstractTypeDeclarationNode(ancestor, unit);
// if (kind == IScriptElement.TYPE || kind == IScriptElement.PACKAGE_DECLARATION || kind == IScriptElement.IMPORT_DECLARATION || kind == IScriptElement.IMPORT_CONTAINER)
// return unit;
// return null;
// }
//
// private static IType getAncestorType(IModelElement destinationElement) {
// return destinationElement.getElementType() == IModelElement.TYPE ? (IType)destinationElement: (IType)destinationElement.getAncestor(IModelElement.TYPE);
// }
// private ASTNode createNewNodeToInsertToCu(TypedSource source, ASTRewrite rewrite) {
// switch(source.getType()){
// case IScriptElement.TYPE:
// return rewrite.createStringPlaceholder(source.getSource(), ASTNode.TYPE_DECLARATION);
// case IScriptElement.PACKAGE_DECLARATION:
// return rewrite.createStringPlaceholder(source.getSource(), ASTNode.PACKAGE_DECLARATION);
// case IScriptElement.IMPORT_DECLARATION:
// return rewrite.createStringPlaceholder(source.getSource(), ASTNode.IMPORT_DECLARATION);
// default: Assert.isTrue(false, String.valueOf(source.getType()));
// return null;
// }
// }
//
// private ASTNode createNewNodeToInsertToType(TypedSource source, ASTRewrite rewrite) {
// switch(source.getType()){
// case IScriptElement.TYPE:
// return rewrite.createStringPlaceholder(source.getSource(), ASTNode.TYPE_DECLARATION);
// case IScriptElement.METHOD:
// return rewrite.createStringPlaceholder(source.getSource(), ASTNode.METHOD_DECLARATION);
// case IScriptElement.FIELD:
// return rewrite.createStringPlaceholder(source.getSource(), ASTNode.FIELD_DECLARATION);
// case IScriptElement.INITIALIZER:
// return rewrite.createStringPlaceholder(source.getSource(), ASTNode.INITIALIZER);
// default: Assert.isTrue(false);
// return null;
// }
// }
//
// private ISourceModule getDestinationCu() {
// return ReorgUtils.getSourceModule(fDestination);
// }
//
// public String getName() {
// return ReorgMessages.PasteAction_name;
// }
// }
// }
}